﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using LogicNP.ShellObjects;

namespace CheckingLine
{
    public partial class Form1 : Form
    {
        private static NLog.Logger _logger = NLog.LogManager.GetCurrentClassLogger();
        private Worker _worker;
        public Form1()
        {
            InitializeComponent();
            shellNotifyIcon1.Visible = true;
            this.SizeChanged += OnSizeChanged;
            this.Shown += OnShown;

            Start();
        }

        private void OnShown(object sender, EventArgs eventArgs)
        {
            System.Diagnostics.Debug.WriteLine("shown");
            this.listBox1.DataSource = _logs;
            //this.listBox1 .Refresh();
        }

        private void OnSizeChanged(object sender, EventArgs eventArgs)
        {
            if (FormWindowState.Minimized == this.WindowState)
            {
                //shellNotifyIcon1.Visible = true;
                shellNotifyIcon1.MinimizeToTray(this, FormAnimStyles.SystemDefault);

            }

            else if (FormWindowState.Normal == this.WindowState)
            {
                //shellNotifyIcon1.Visible = false;
            }
        }

        private readonly BindingList<string> _logs = new BindingList<string>();
        private void Logger(string msg)
        {

            Action<string> action = s =>
                                    {
                                        _logs.Add(DateTime.Now.ToString() + ": " + s);
                                        if (_logs.Count > 100)
                                        {
                                            _logs.RemoveAt(0);
                                        }

                                        listBox1.SelectedIndex = listBox1.Items.Count - 1;
                                    };
            if (this.Visible)
            {
                this.BeginInvoke(action, msg);
            }
            else
                action(msg);
        }

        private void buttonStart_Click(object sender, EventArgs e)
        {
            StartCapturer();
        }

        private void StartCapturer()
        {
            if (_worker != null)
            {
                _worker.Stop();
                _worker.Logger = s => { };
                _worker.LprCapturred -= WorkerOnLprCapturred;
            }

            try
            {
                if (!string.IsNullOrEmpty(Properties.Settings.Default.CameraIp))
                {
                    var sections = Properties.Settings.Default.Roi.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                    var x = int.Parse(sections[0]);
                    var y = int.Parse(sections[1]);
                    var w = int.Parse(sections[2]);
                    var h = int.Parse(sections[3]);
                    var roi = new Rectangle(x, y, w, h);

                    _worker = new Worker(
                        Properties.Settings.Default.RequestFilePath, Properties.Settings.Default.ResultFilePath,
                        Properties.Settings.Default.CameraIp, int.Parse(Properties.Settings.Default.CameraPort), 0, Properties.Settings.Default.UserName, Properties.Settings.Default.Password,
                        roi, Properties.Settings.Default.Provience);

                    _worker.Logger = this.Logger;
                    _worker.LprCapturred += WorkerOnLprCapturred;
                    _worker.Start();
                }
                else
                {
                    MessageBox.Show("请先配置系统选项");
                }
            }
            catch (Exception ex)
            {
                Logger("启动抓拍时发生异常：" + ex.Message);
            }



        }

        private void WorkerOnLprCapturred(object sender, LprCapturedEventArgs lprCapturedEventArgs)
        {
            Action action = () =>
                            {
                                this.labelLprNumber.Text = lprCapturedEventArgs.Result.Succeed
                                    ? lprCapturedEventArgs.Result.PlateNumber
                                    : "未识别";
                                this.pictureBox1.Image = (Image)lprCapturedEventArgs.Image.Clone();
                            };
            if (this.Visible)
            {
                this.BeginInvoke(action);
            }
        }

        private void buttonTestImage_Click(object sender, EventArgs e)
        {
            if (_worker != null)
            {
                var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "1 vehicle.jpg");
                var bytes = File.ReadAllBytes(path);
                var img = Image.FromStream(new MemoryStream(bytes));
                _worker.AddImage(img);
            }
            else
                MessageBox.Show("请先启动识别");
        }

        private void buttonTrigger_Click(object sender, EventArgs e)
        {
            if (_worker != null)
            {
                _worker.TriggerOnce();
            }
            else
                MessageBox.Show("请先启动识别");
        }

        private void buttonOptions_Click(object sender, EventArgs e)
        {
            using (var form = new OptionsForm())
            {
                var result = form.ShowDialog(this);
                if (result == DialogResult.OK)
                {
                    Properties.Settings.Default.Save();
                }
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
        }

        private void Start()
        {
            try
            {
                Worker.InitRecognizer();
                StartCapturer();
                System.Diagnostics.Debug.WriteLine("loaded");
            }
            catch (Exception ex)
            {
                Logger("初始化车牌模块出现异常");
                _logger.ErrorException("初始化车牌识别发生异常", ex);
            }
        }

        private bool _allowedToShow = false;
        protected override void SetVisibleCore(bool value)
        {
            base.SetVisibleCore(_allowedToShow ? value : _allowedToShow);
        }

        private void shellNotifyIcon1_Click(object sender, EventArgs e)
        {
            _allowedToShow = true;
            this.Visible = !this.Visible;
            if (this.Visible)
            {
                shellNotifyIcon1.MaximizeFromTray(this, FormAnimStyles.SystemDefault);
            }

            //shellNotifyIcon1.Visible = !shellNotifyIcon1.Visible;
        }

        private void Form1_DragEnter(object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.All;
        }


        private string[] fileExtensions = new string[] { ".jpg", ".bmp" };
        private void Form1_DragDrop(object sender, DragEventArgs e)
        {
            if (_worker != null)
            {
                if (e.Data.GetDataPresent(DataFormats.FileDrop))
                {
                    var files = (string[])e.Data.GetData(DataFormats.FileDrop);
                    var ext = Path.GetExtension(files[0]);
                    if (!string.IsNullOrEmpty(ext) && fileExtensions.Contains(ext))
                    {
                        var bytes = File.ReadAllBytes(files[0]);
                        _worker.AddImage(Image.FromStream(new MemoryStream(bytes)));
                    }
                }
            }


        }

        private void Form1_DragOver(object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.All;
        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {

        }
    }
}
